<?php
/**
 * (logic) 运营总表
 */
namespace App\Logic\Operation;

use App\Models\Basics\AmazonCountry;
use App\Models\Basics\ExchangeRate;
use App\Models\Operation\BATotal;
use App\Models\Operation\ProfitSku;
use App\Models\Operation\TCTotal;
use App\Models\Operation\TCTotalDetail;
use App\Models\Product\ProductSku;
use App\Models\SalesAmazon\SalesAmountDay;
use App\Models\SalesAmazon\SalesVolumeDay;
use Illuminate\Support\Facades\DB;
class CheckProfitOperation
{

    public static function handle()
    {
        $rate = [];
        $classify = [];
        //运营总表
        BATotal::query()
            ->where('report_date','>=','2024-01-14')
            ->orderBy('id')
            ->chunk(800, function ($items) use (&$rate,&$classify){
                DB::beginTransaction();
                try{
                    foreach ($items as $item){
                        $date = $item->report_date;
                        $_date = date("Ymd",strtotime($date));

                        if(!array_key_exists($item->country_id,$rate)){
                            $currencyCode = AmazonCountry::getCurrencyCodeByCountryId($item->country_id);
                            $rate[$item->country_id] = ExchangeRate::getRateOddsToRMB($currencyCode,strtotime($date));
                        }
                        $rateOdds = $rate[$item->country_id];

                        if(!array_key_exists($item->classify_id,$classify)){
                            $classify[$item->classify_id] = ProductSku::query()
                                ->where('classify_id',$item->classify_id)
                                ->pluck('id')
                                ->toArray();
                        }
                        $pSkuIds = $classify[$item->classify_id];
                        //利润
                        $item->profit = self::_getProfit($date,$_date,$rateOdds,$item->country_id,$item->classify_id,$pSkuIds,$item->spend,$item->reimburse,$item->promotion_discount);
                        $item->save();
                    }
                    DB::commit();
                }catch (\Exception $e){
                    DB::rollBack();
                    report($e);
                }
        });
    }

    private static function _getProfit($date,$_date,$rateOdds,$countryId,$classifyId,$pSkuIds,$spend,$reimburse,$promotionDiscount): float
    {
        $amounts = SalesAmountDay::query()
            ->where('day',$_date)
            ->where('country_id',$countryId)
            ->whereIn('psku_id',$pSkuIds)
            ->select(DB::raw('sum(amount) as amount,psku_id'))
            ->groupBy('psku_id')
            ->get();
        $profit = 0;
        $tcItem = [];
        foreach ($amounts as $amount){
            $item = ProfitSku::query()
                ->where('psku_id',$amount->psku_id)
                ->where('country_id',$countryId)
                ->where('transport',1)
                ->first();
            $temp = [];
            $temp['amount'] = $amount->amount;
            if($item){
                $volume = SalesVolumeDay::query()
                    ->where('day',$_date)
                    ->where('country_id',$countryId)
                    ->where('psku_id',$amount->psku_id)
                    ->sum('volume');
                $tpl = round($volume * $item->tpl_rmb / $item->rate_odds,3);
                $headCost = $volume * $item->head_cost;
                $fbaFee = $volume * $item->fba_fee;
                $cost = ProfitSku::getCost($tpl,$amount->amount,$headCost,$fbaFee,$item->commission,$item->return,$item->vat);
                $temp['volume'] = $volume;
                $temp['tpl_rmb'] = $item->tpl_rmb;
                $temp['head_cost'] = $item->head_cost;
                $temp['fba_fee'] = $item->fba_fee;
                $temp['commission'] = $item->commission;
                $temp['return'] = $item->return;
                $temp['vat'] = $item->vat;
                $temp['cost'] = $cost;
            }else{
                $temp['cost'] = 0;
                $cost = 0;
            }
            $_profit = round(($amount->amount - $cost),3);
            $temp['profit'] = $_profit;
            $profit += $_profit * $rateOdds;
            $tcItem[$amount->psku_id] = $temp;
        }
        $item = [];
        $item['report_date'] = $date;
        $item['country_id'] = $countryId;
        $item['classify_id'] = $classifyId;
        $item['rate_odds'] = $rateOdds;
        $item['spend'] = $spend;
        $item['reimburse'] = $reimburse;
        $item['promotion_discount'] = $promotionDiscount;
        $profitMinus = round($profit - $spend - $reimburse - $promotionDiscount,3);
        $item['profit'] = $profitMinus;

        //运营总表
        self::_store($item,$tcItem);

        return $profitMinus;
    }

    /**
     * 核验运营总表
     * @param $item
     * @param $tcItem
     */
    private static function _store($item,$tcItem){
        //运营总表
        $tcTotal = TCTotal::query()->firstOrNew(['report_date' => $item['report_date'], 'country_id' => $item['country_id'], 'classify_id' => $item['classify_id']]);
        foreach ($item as $k => $value ){
            if(in_array($k,['report_date','country_id','classify_id']))continue;
            $tcTotal->{$k} = $value;
        }
        $tcTotal->save();
        //运营总表明细
        foreach ($tcItem as $pSkuId => $_tcItem){
            TCTotalDetail::query()->updateOrCreate(['tc_id' => $tcTotal->id,'psku_id' => $pSkuId],$_tcItem);
        }
    }
}
